/************************************************************
 * Copyright (C), 2022-2030, dina. Co., Ltd.
 * FileName:        serialport_mgr.h
 * Author:          Dan Yin
 * Date:            2022-11-23
 * Description:     the class of serialport manager
 * Version:         1.0.0.0
 **********************************************************/

#ifndef SERIALPORT_MGR_H
#define SERIALPORT_MGR_H

#include <QThread>
#include <QSerialPort>
#include <QTimer>
#include "serialport_plugin.h"
#include "cycle_buffer.h"

class SerialportMgr : public QThread
{
    Q_OBJECT
public:
    // Get an instance of "SerialportMgr" class, if exist, return it
    static SerialportMgr* getInstance(QObject *pParent = nullptr);

    // The default destructor
    virtual ~SerialportMgr();

    // open a serial port
    int openCOM();

    // close a serial port
    void closeCOM();

    // write data into COM
    int writeData(const QByteArray &baInput, const bool bQueued);

    // send & receive data
    int fetchData(QByteArray &baOutput, const QByteArray &baInput, const int nSleep=1000);

signals:
    // the signal that received data from COM
    void signalDataReceived(const QByteArray &baData);

private slots:
    // received data from COM
    void slotDataReceived();

    // Fetch data from COM
    void slotPayloadFetched(const QByteArray &baData);

    // reply an ACK command to COM
    int slotReplyACK(QByteArray baPacket, bool bQueued);

    // write data to COM
    void slotSendDataTimer();

protected:
    // default thread function
    void run() Q_DECL_OVERRIDE;

private:
    // The default constructor
    explicit SerialportMgr(QObject *parent = nullptr);

    // After constructing object, initialize the object
    void _initialze();

    // the command handler
    void _commandHandler();

    // Concatenated data packet from COM
    int _concatenatedData(QByteArray baRecv);

private:
    // the serialport class
    QSerialPort * m_pSerialPort = nullptr;

    // the buffer for serialport
    CycleBuffer<char> m_bufRecv;

    // Is running thread?
    bool m_bRunning = true;

    // write data timer
    QTimer *m_pWriteDataTimer = nullptr;
};

#endif // SERIALPORT_MGR_H
